﻿using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.InkML;
using IDEAMS.core;
using IDEAMS.core.deviceClient;
using IDEAMS.core.opm;
using IDEAMS.core.queue;
using IDEAMS.model;
using IDEAMS.model.alarm;
using IDEAMS.model.dataAcquisition;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Windows;

namespace IDEAMS.view.detection
{
    /// <summary>
    /// DataAcquisitionDlg.xaml 的交互逻辑
    /// </summary>
    public partial class DataAcquisitionDlg : Window
    {
        public DataAcquisitionDlgViewModel windowViewModel;
        private DeviceClient client;

        /// <summary>
        /// 波长接收线程
        /// </summary>
        OPM_MsgWorker peaksRefreshMsgWorker = null;
        private readonly object peaksLocker = new object(); //peaks 发现的locker

        public DataAcquisitionDlg()
        {
            InitializeComponent();

            this.Closing += new System.ComponentModel.CancelEventHandler(Window_Closing);

        }

        public DataAcquisitionDlg(DeviceInfoViewModel deviceInfo) : this()
        {
            this.btnStart.Click += new RoutedEventHandler(Start_Click);
            this.btnEnd.Click += new RoutedEventHandler(End_Click);

            this.btnPass.Click += new RoutedEventHandler(Pass_Click);
            this.btnFail.Click += new RoutedEventHandler(Fail_Click);
            this.btnCancel.Click += new RoutedEventHandler(Cancel_Click);

            windowViewModel = new DataAcquisitionDlgViewModel();
            this.DataContext = windowViewModel;

            windowViewModel.deviceInfo = deviceInfo.Clone();
            switch (deviceInfo.step)
            {
                case ProcessStep.PRE_DATA_ACQUISITION:
                    windowViewModel.title = "数据采集（烤机前）";
                    break;
                case ProcessStep.POST_DATA_ACQUISITION:
                    windowViewModel.title = "数据采集（烤机后）";
                    break;
                default:
                    break;
            }

            client = TW_App.deviceClientManager.Find(deviceInfo.serialNo);

            peaksRefreshMsgWorker = CreatePeaksRefreshWorker();

            waveList = new List<Wave>();
        }

        DateTime dt;
        private void Start_Click(object sender, RoutedEventArgs e)
        {
            this.btnStart.IsEnabled = false;
            waveList.Clear();

            if (client != null && !client.dataWorker.isWaveStart)
            {
                client.dataWorker.OPMStart();
                client.dataWorker.isWaveStart = true;
            }
            dt = DateTime.Now;
            //Thread th = new Thread(new ThreadStart(DataProcessing));
            //th.Start();

            ProgressingDlg progressingDlg = new ProgressingDlg("数据采集", "数据采集中，请稍候...", new DoWorkEventHandler((object s, DoWorkEventArgs args) =>
            {
                DataProcessing();
            }));


            progressingDlg.Owner = this;
            progressingDlg.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            progressingDlg.Show();


            StartPeaksRefreshWorker();
        }

        List<List<CollectData>> dataList;
        private void DataProcessing()
        {
            while ((DateTime.Now - dt).TotalSeconds < 60)
            {
                Thread.Sleep(1);
            }

            if (client != null && client.dataWorker.isWaveStart)
            {
                client.dataWorker.isWaveStart = false;
            }

            dataList = new List<List<CollectData>>();

            for (int i = 0; i < waveList.Count; i++)
            {
                for (int j = 0; j < waveList[i].nChannel; j++)
                {
                    if (i == 0)
                    {
                        dataList.Add(new List<CollectData>());
                    }

                    if (waveList[i].chGratting[j].waveValueArray == null)
                    {
                        continue;
                    }

                    for (int k = 0; k < waveList[i].chGratting[j].waveValueArray.Length; k++)
                    {
                        if (i == 0)
                        {
                            CollectData data = new CollectData();
                            data.name = "C" + (j + 1) + "_S" + (k + 1);
                            data.channelNo = j + 1;
                            data.gratingNo = k + 1;
                            data.maxValue = double.MinValue;
                            data.minValue = double.MaxValue;
                            data.avgValue = 0;
                            data.count = 0;
                            dataList[j].Add(data);
                        }

                        double value = waveList[i].chGratting[j].waveValueArray[k];
                        CollectData d = dataList[j][k];
                        if (value > d.maxValue)
                        {
                            d.maxValue = value;
                        }
                        if (value < d.minValue)
                        {
                            d.minValue = value;
                        }
                        d.sum += value;
                        d.count++;
                        d.avgValue = d.sum / d.count;
                        d.values.Add(value);
                    }
                }
            }

            App.Current.Dispatcher.Invoke((Action)(() => {
                foreach (var item in dataList)
                {
                    foreach (var item1 in item)
                    {
                        windowViewModel.collectDatas.Add(new CollectDataViewModel(item1));
                    }
                }
                this.btnStart.IsEnabled = true;
            }));
        }

        private void End_Click(object sender, RoutedEventArgs e)
        {
            if (client != null && client.dataWorker.isWaveStart)
            {
                client.dataWorker.isWaveStart = false;
            }
        }

        private void Pass_Click(object sender, RoutedEventArgs e)
        {
            if (windowViewModel.collectDatas.Count <= 0)
            {
                MessageBox.Show("请先采集数据", "提示", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }
            switch (windowViewModel.deviceInfo.step)
            {
                case ProcessStep.PRE_DATA_ACQUISITION:
                    windowViewModel.deviceInfo.processResult.preDataAcquisition = true;
                    break;
                case ProcessStep.POST_DATA_ACQUISITION:
                    windowViewModel.deviceInfo.processResult.preDataAcquisition = true;
                    break;
                default:
                    break;
            }

            CollectDataCollection collection = new CollectDataCollection();
            foreach (var item in windowViewModel.collectDatas)
            {
                collection.Add(new CollectData(item));
            }
            collection.Save(windowViewModel.deviceInfo.serialNo, windowViewModel.deviceInfo.step);

            // 查询当前检测步骤
            int index = TW_App.globalSetting.inspectionSequences.IndexOf((int)windowViewModel.deviceInfo.step);
            if (index == -1)
            {
                MessageBox.Show("当前处于未知检测项，请联系系统管理员", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (index == TW_App.globalSetting.inspectionSequences.Count - 1)
            {
                windowViewModel.deviceInfo.step = ProcessStep.FINISHED;
            }
            else
            {
                windowViewModel.deviceInfo.step = (ProcessStep)TW_App.globalSetting.inspectionSequences[index + 1];
            }

            if(client != null && client.dataWorker.isWaveStart)
            {
                client.dataWorker.isWaveStart = false;
            }

            this.DialogResult = true;
        }

        private void Fail_Click(object sender, RoutedEventArgs e)
        {
            switch (windowViewModel.deviceInfo.step)
            {
                case ProcessStep.PRE_DATA_ACQUISITION:
                    windowViewModel.deviceInfo.processResult.preDataAcquisition = false;
                    break;
                case ProcessStep.POST_DATA_ACQUISITION:
                    windowViewModel.deviceInfo.processResult.postDataAcquisition = false;
                    break;
                default:
                    break;
            }

            if(client != null && client.dataWorker.isWaveStart)
            {
                client.dataWorker.isWaveStart = false;
            }
            this.DialogResult = true;
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            if(client !=null && client.dataWorker.isWaveStart)
            {
                client.dataWorker.isWaveStart = false;
            }
            this.DialogResult = false;
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            //client.dataWorker.OPMStop();
            Thread th = new Thread(new ThreadStart(StopPeaksRefreshWorker));
            th.Start();
        }


        private OPM_MsgWorker CreatePeaksRefreshWorker()
        {
            OPM_MsgWorker worker = new OPM_MsgWorker();
            worker.handleProc = PeaksDataRefreshProc;
            worker.keyList.Add(QueueDataType.DATA_WL);

            return worker;
        }

        private void StartPeaksRefreshWorker()
        {
            if (peaksRefreshMsgWorker.IsStop())
            {
                if (client != null)
                {
                    client.Register(peaksRefreshMsgWorker, QueueDataType.DATA_WL);
                }
                peaksRefreshMsgWorker.StartAsync();
            }
        }

        private void StopPeaksRefreshWorker()
        {
            if (!peaksRefreshMsgWorker.IsStop())
            {
                peaksRefreshMsgWorker.Stop();
                if (client != null)
                {
                    client.UnRegister(peaksRefreshMsgWorker, QueueDataType.DATA_WL);
                }
            }
        }

        // 存储2分钟数据
        List<Wave> waveList;

        private void PeaksDataRefreshProc(QueueData msg)
        {
            //发现peaks锁
            lock (peaksLocker)
            {
                Wave waveLenData = (Wave)msg;

                waveList.Add(waveLenData);

            }
        }
    }

    public class DataAcquisitionDlgViewModel : ViewModelBase
    {
        public DataAcquisitionDlgViewModel()
        {
            collectDatas = new ObservableCollection<CollectDataViewModel>();
        }

        private string m_title;
        public string title
        {
            get { return m_title; }
            set
            {
                m_title = value;
                NotifyPropertyChanged();
            }
        }

        private DeviceInfoViewModel m_deviceInfo;
        public DeviceInfoViewModel deviceInfo
        {
            get { return m_deviceInfo; }
            set
            {
                m_deviceInfo = value;
                NotifyPropertyChanged();
            }
        }

        private ObservableCollection<CollectDataViewModel> m_collectDatas;
        public ObservableCollection<CollectDataViewModel> collectDatas
        {
            get { return m_collectDatas; }
            set
            {
                m_collectDatas = value;
                NotifyPropertyChanged();
            }
        }
    }
}
